In modern computer system development with the reduction of individual hardware development, it is becoming common to emulate one machine instruction set on an entirely different system by another using a process called binary translation. This process is implemented for a number of reasons, including:
1. Emulation of machine code of a first system on a different instruction set architecture.
2. Increasing the performance of the source code.
3. Monitoring execution flow to isolate problem areas.
4. Debugging code, especially random execution failures.
Generally, translation of binary code includes translation from a first, non-native code executable using a computing system that implements a non-native instruction set architecture to native code executable on a target computing system implementing a native instruction set architecture.
The reasons for translating one system's instruction set to execute on different hardware and software platforms are numerous. For example, the source system hardware may no longer physically exist but its operating system and user programs need to be retained as a viable product line. As a result, the source operating system and its application suite will be translated to run on different logical and physical platforms. Additionally, it is often the case that the performance of some code could be enhanced by translating it to run on another system platform. Specifically, it is possible that the source instruction set can be more effectively mapped to a new hardware and operating system platform thus yielding an increase in performance and greater economic viability.
In addition to the above, using binary translation to emulate one operating system and its applications on another (target) system has potential to enhance monitoring capabilities that will facilitate performance data collection and analysis, for example by using tools available on that target system. Still another area of system development that might benefit from translation and emulation is the increased ability to debug problems, especially those of an intermittent nature, using increasingly advanced tools available on such target systems.
Given the above advantages of binary translation of software from a source instruction set architecture to a target instruction set architecture, increasing efforts have been focused on determining an efficient process for performing binary translation. For example, some systems implement static translation, in which non-native code is translated to native code prior to execution of that native code on a target computing system implementing a native instruction set architecture. Other systems implement dynamic translation, in which non-native code is translated to native code “on the fly”, while executed at the target computing system.
Regardless of the type of translation performed, systems that perform binary translation have many challenges. One challenge involved in translating between computing systems relates to memory addressing and access of data referenced in the instructions defined by the non-native code. That is, non-native binary code to be translated generally includes a series of instructions that each indicate an operation to be performed, such as an addition or multiplication operation, as well data required by the instruction to perform the identified function. This data can, in many circumstances, be an address of data (e.g., an operand) to be used in the operation to be performed. Accordingly, translating binary code can include translating a memory address from the memory addressing scheme provided by the non-native architecture (i.e., the location of the operand) to the memory addressing scheme provided by the target computing system, within the native architecture. This can include, for example, translating an address calculated and typically stored in one or more addressing registers, the equivalent of which may not be available on the target system. It can also include performing one or more verification operations, for example to determine validity of an address to be used to store a particular operand, i.e., whether the resulting address to be used is within the bounds of acceptable addresses to be used by the program being translated. However, when validation of each address defining an operand location is required by the translation, both the translation and subsequent execution of translated code can be time consuming, and can result in reduced performance, whether the translation that is performed is static or dynamic.
For these and other reasons, improvements are desirable.